import { isObject, isArray, isRegExp, isString } from './validate';

// 获取对象中的某些属性，返回的新对象
export function objectPick<T extends object>(obj: object, props: string | string[]): T {
  if (typeof props == 'string') {
    props = props.split(',');
  }
  return Object.fromEntries(Object.entries(obj).filter(([k]) => props.includes(k))) as T;
}

// 忽略对象中的某些属性，返回新的对象
export function objectOmit<T extends object>(obj: object, props: string | string[]): T {
  if (typeof props == 'string') {
    props = props.split(',');
  }
  return Object.fromEntries(Object.entries(obj).filter(([k]) => !props.includes(k))) as T;
}

// 创建对象格式化键或值的新对象
export function objectFormatKey<T extends object>(obj: object, format: RegExp | Function): T {
  const result: any = {};
  for (const [key, value] of Object.entries(obj)) {
    let k: any = key;
    if (isRegExp(format)) {
      k = key.replace(format as RegExp, '$1');
    } else {
      k = (format as Function)(key, value);
    }
    result[k] = value;
  }
  return result;
}

// 创建对象格式化键或值的新对象
export function objectFormatValue<T extends object>(obj: object, format: RegExp | Function): T {
  const result: any = {};
  for (const [key, value] of Object.entries(obj)) {
    let v = value;
    if (isRegExp(format)) {
      v = value.replace(format as RegExp, '$1');
    } else {
      v = (format as Function)(value, key);
    }
    result[key] = v;
  }
  return result;
}

// 嵌套对象扁平化
export function objectFlatten(obj: object, connector = '.'): object {
  const result: any = {};
  function recurse(data: any, prop: string) {
    if (isObject(data)) {
      for (const [k, v] of Object.entries(data)) {
        recurse(v, prop ? `${prop}${connector}${k}` : k);
      }
    } else {
      result[prop] = data;
    }
  }
  recurse(obj, '');
  return result;
}

// 扁平对象嵌套化
export function objectNested(obj: object, connector = '.'): object {
  let result: any = {};
  function recurse(obj: any, keys: string[], value: any) {
    let current = obj;
    for (let i = 0; i < keys.length - 1; i++) {
      if (!current[keys[i]]) {
        current[keys[i]] = {};
      }
      current = current[keys[i]];
    }
    current[keys[keys.length - 1]] = value;
  }
  for (const [k, v] of Object.entries(obj)) {
    const keys = k.split(connector);
    recurse(result, keys, v);
  }
  return result;
}

// 对象转文本内容
export function objectToContent(value: any, prefix = '', deep = 1): string {
  const space = `  `;
  if (isObject(value)) {
    let attrsLine: string[] = [];
    for (const [k, v] of Object.entries(value)) {
      const attr = space.repeat(deep) + `"${k}": ${objectToContent(v, '', deep + 1)}`;
      attrsLine.push(attr);
    }
    const endLine = `\r${space.repeat(deep - 1)}}`;
    return `${prefix}{\r` + attrsLine.join(',\r') + endLine;
  }
  if (isArray(value)) {
    let attrsLine: string[] = [];
    for (let i = 0; i < value.length; i++) {
      const attr = space.repeat(deep) + `${objectToContent(value[i], '', deep + 1)}`;
      attrsLine.push(attr);
    }
    const endLine = `\r${space.repeat(deep - 1)}]`;
    return `${prefix}[\r` + attrsLine.join(',\r') + endLine;
  }
  if (isString(value)) {
    return `"${value.replace(/(?<!\\)"/g, '\\"')}"`.replace(/\n/g, '\\n');
  }
  return value;
}
